package com.zjcloud.framework.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * Service方法执行日志切面
 *
 * @author zjcloud
 */
@Aspect
@Component
public class ServiceLogAspect {

    private static final Logger log = LoggerFactory.getLogger(ServiceLogAspect.class);

    /**
     * 定义切点 - 所有Service接口的方法
     */
    @Pointcut("execution(* com.zjcloud..*.service.*Service.*(..))") 
    public void serviceMethodPointcut() {}

    /**
     * 环绕通知，记录Service方法执行的开始和结束日志
     *
     * @param joinPoint 连接点
     * @return 方法执行结果
     * @throws Throwable 执行异常
     */
    @Around("serviceMethodPointcut()")
    public Object aroundServiceMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取类名
        String className = joinPoint.getTarget().getClass().getName();
        String simpleClassName = joinPoint.getTarget().getClass().getSimpleName();
        
        // 获取方法名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();
        
        // 获取参数
        Object[] args = joinPoint.getArgs();
        
        // 记录开始日志
        long startTime = System.currentTimeMillis();
        log.debug("开始执行Service方法: {}.{}", simpleClassName, methodName);
        
        // 执行原方法
        Object result = null;
        try {
            result = joinPoint.proceed();
            return result;
        } catch (Throwable e) {
            log.error("执行Service方法异常: {}.{}, 异常信息: {}", simpleClassName, methodName, e.getMessage());
            throw e;
        } finally {
            // 记录结束日志
            long endTime = System.currentTimeMillis();
            long costTime = endTime - startTime;
            log.debug("结束执行Service方法: {}.{}, 耗时: {}ms", simpleClassName, methodName, costTime);
        }
    }
}